package net.projecteuler.prob;

import java.util.Arrays;

import net.projecteuler.util.DigitUtil;

public class Problem43 implements Runnable {

	int[] panDigits = new int[10];
	boolean[] check = new boolean[10];
	
	@Override
	public void run() {
		// d1
		for(int d1d2d3 = 100; d1d2d3 < 1000; d1d2d3++){
			int[] digits = DigitUtil.digits(d1d2d3, 10, true);
			if(digits[0] != digits[1] && digits[0] != digits[2] && digits[2] != digits[1]){
				panDigits[0] = digits[0];
				panDigits[1] = digits[1];
				panDigits[2] = digits[2];
				
				check[panDigits[0]] = true;
				check[panDigits[1]] = true;
				check[panDigits[2]] = true;
				
				setD4();
	
				check[panDigits[0]] = false;
				check[panDigits[1]] = false;
				check[panDigits[2]] = false;
			}
		}
	}

	private void setD4() {
		for(int i = 0; i < 10; i += 2){
			if(check[i] == false){
				panDigits[3] = i;
				check[i] = true;

				setD5();				

				check[i] = false;
			}
		}
	}

	private void setD5() {
		int remainder = (panDigits[2] * 100 + panDigits[3] * 10) % 3;
		int d5_1 = (3 - remainder) % 3;
		int[] d5 = null;
		if(d5_1 == 0){
			d5 = new int[4];
			d5[0] = 0;
			d5[1] = 3;
			d5[2] = 6;
			d5[3] = 9;
		} else {
			d5 = new int[3];
			d5[0] = d5_1;
			d5[1] = d5_1 + 3;
			d5[2] = d5_1 + 6;
		}
		
		for(int i = 0; i < d5.length; i++){
			if(check[d5[i]] == false){
				panDigits[4] = d5[i];
				check[d5[i]] = true;

				setD6();				

				check[d5[i]] = false;
			}
		}
	}

	private void setD6() {
		for(int i = 0; i < 10; i += 5){
			if(check[i] == false){
				panDigits[5] = i;
				check[i] = true;

				setD7();				

				check[i] = false;
			}
		}
	}

	private void setD7() {
		int remainder = (panDigits[4] * 100 + panDigits[5] * 10) % 7;
		int d7_1 = (7 - remainder) % 7;
		int[] d7 = null;
		if(d7_1 < 3){
			d7 = new int[2];
			d7[0] = d7_1;
			d7[1] = d7_1 + 7;
		} else {
			d7 = new int[1];
			d7[0] = d7_1;
		}
		
		for(int i = 0; i < d7.length; i++){
			if(check[d7[i]] == false){
				panDigits[6] = d7[i];
				check[d7[i]] = true;

				setD8();				

				check[d7[i]] = false;
			}
		}
	}

	private void setD8() {
		int remainder = (panDigits[5] * 100 + panDigits[6] * 10) % 11;
		int d7 = (11 - remainder) % 11;
		if(d7 > 9)
			return;
		
		if(check[d7] == false){
			panDigits[7] = d7;
			check[d7] = true;

			setD9();				

			check[d7] = false;
		}
	}

	private void setD9() {
		int remainder = (panDigits[6] * 100 + panDigits[7] * 10) % 13;
		int d8 = (13 - remainder) % 13;
		if(d8 > 9)
			return;
		
		if(check[d8] == false){
			panDigits[8] = d8;
			check[d8] = true;

			setD10();				

			check[d8] = false;
		}
	}

	private void setD10() {
		int remainder = (panDigits[7] * 100 + panDigits[8] * 10) % 17;
		int d8 = (17 - remainder) % 17;
		if(d8 > 9)
			return;
		
		if(check[d8] == false){
			panDigits[9] = d8;
			String str = "";
			for(int i = 0; i < 10; i++)
				str += panDigits[i] + "";
			System.out.println(str);
		}
	}
}
